package com.vcc.service.impl;

import cn.hutool.core.map.MapUtil;
import com.mybatisflex.core.update.UpdateChain;
import com.mybatisflex.spring.service.impl.ServiceImpl;
import com.vcc.core.exception.ProgramException;
import com.vcc.data.entity.ClientParam;
import com.vcc.data.mapper.ClientParamMapper;
import com.vcc.service.boss.request.clientParam.BossClientParamUpdateRequest;
import com.vcc.service.boss.response.clientParam.ClientParamVoBoss;
import com.vcc.service.service.ClientParamService;
import com.vcc.service.service.ClientUserParamService;
import jakarta.annotation.Resource;
import lombok.extern.log4j.Log4j2;
import org.apache.commons.lang3.StringUtils;
import org.springframework.stereotype.Service;

import java.util.HashMap;
import java.util.List;
import java.util.Map;

import static com.vcc.data.entity.table.ClientParamTableDef.CLIENT_PARAM;

@Service
@Log4j2
public class ClientParamServiceImpl extends ServiceImpl<ClientParamMapper, ClientParam> implements ClientParamService {

    @Resource
    private ClientUserParamService clientUserParamService;

    @Override
    public List<ClientParamVoBoss> list(String code, String name, Boolean hasUserConfig) {
        return queryChain().where(CLIENT_PARAM.CODE.like(code, StringUtils.isNotBlank(code)))
                .and(CLIENT_PARAM.NAME.like(name, StringUtils.isNotBlank(name)))
                .and(CLIENT_PARAM.HAS_USER_CONFIG.eq(hasUserConfig, hasUserConfig != null))
                .select(CLIENT_PARAM.ALL_COLUMNS)
                .listAs(ClientParamVoBoss.class);
    }

    @Override
    public Boolean existsByCode(String code) {
        return queryChain()
                .where(CLIENT_PARAM.CODE.eq(code))
                .exists();
    }

    @Override
    public Boolean updateClientParam(BossClientParamUpdateRequest bossClientParamUpdateRequest) {
        getByIdOpt(bossClientParamUpdateRequest.getId())
                .orElseThrow(() -> new IllegalArgumentException("ClientParam not found"));
        UpdateChain<ClientParam> updatedChain = updateChain();
        if (StringUtils.isNotBlank(bossClientParamUpdateRequest.getName())) {
            updatedChain.set(CLIENT_PARAM.NAME, bossClientParamUpdateRequest.getName());
        }
        if (StringUtils.isNotBlank(bossClientParamUpdateRequest.getValue())) {
            updatedChain.set(CLIENT_PARAM.VALUE, bossClientParamUpdateRequest.getValue());
        }
        if (bossClientParamUpdateRequest.getHasUserConfig() != null) {
            updatedChain.set(CLIENT_PARAM.HAS_USER_CONFIG, bossClientParamUpdateRequest.getHasUserConfig());
        }
        updatedChain.where(CLIENT_PARAM.ID.eq(bossClientParamUpdateRequest.getId()));
        return updatedChain.update();
    }

    @Override
    public ClientParam getByCode(String code) {
        return queryChain()
                .where(CLIENT_PARAM.CODE.eq(code))
                .oneOpt()
                .orElseThrow(() -> new ProgramException("ClientParam with code " + code + " not found"));
    }

    @Override
    public String getValueByCodeAndUserId(String code, Long userId) {
        ClientParam clientParam = getByCode(code);
        if (clientUserParamService.existsByUserIdAndParamId(userId, clientParam.getId())) {
            return clientUserParamService.getByUserIdAndParamId(userId, clientParam.getId()).getValue();
        } else {
            return clientParam.getValue();
        }
    }

    @Override
    public String getValueByCodeAndUserIdOrDefaultValue(String code, Long userId, String defaultValue) {
        try {
            ClientParam clientParam = getByCode(code);
            if (clientUserParamService.existsByUserIdAndParamId(userId, clientParam.getId())) {
                return clientUserParamService.getByUserIdAndParamId(userId, clientParam.getId()).getValue();
            } else {
                return clientParam.getValue();
            }
        } catch (Exception e) {
            log.error("获取ClientParam的值失败，code: {}, userId: {}, 异常信息: {}", code, userId, e.getMessage(), e);
            return defaultValue;
        }
    }

    @Override
    public Map<Long,String> getValueByCodeAndUserIdsOrDefaultValue(String code, List<Long> userIds, String defaultValue) {
        HashMap<Long, String> clientParamMap = MapUtil.newHashMap();
        for (Long userId : userIds) {
            String value = getValueByCodeAndUserIdOrDefaultValue(code, userId, defaultValue);
            clientParamMap.put(userId, value);
        }
        return clientParamMap;
    }

    @Override
    public Integer sumByUserIdAndRole(Long userId, String role) {
        return 0;
    }
}
